package com.huifer.wgx.service.impl;

import com.huifer.wgx.model.FieldLineEntity;
import com.huifer.wgx.model.FieldPointEntity;
import com.huifer.wgx.model.FileEntity;
import com.huifer.wgx.model.RtkPointEntity;
import com.huifer.wgx.pojo.CsvFieldLine;
import com.huifer.wgx.pojo.CsvFieldPoint;
import com.huifer.wgx.repository.FieldLineRepository;
import com.huifer.wgx.repository.FieldPointRepository;
import com.huifer.wgx.repository.FileRepository;
import com.huifer.wgx.service.FieldLineService;
import com.huifer.wgx.spec.CommonSpec;
import com.huifer.wgx.utlis.CsvUtil;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

/**
 * <p>Title : FieldLineServiceImpl </p>
 * <p>Description : </p>
 *
 * @author huifer
 * @date 2019-03-21
 */
@Service
public class FieldLineServiceImpl implements FieldLineService {

    @Autowired
    private FileRepository fileRepository;
    @Autowired
    private FieldPointRepository pointRepository;
    @Autowired
    private FieldLineRepository lineRepository;

    /**
     * 创建一条外业采集线段
     *
     * @param fieldLineStartPointName 起点点名
     * @param fieldLineStartDeep 起点埋深
     * @param fieldLineEndPointName 终点点名
     * @param fieldLineEndDeep 终点埋深
     * @param fieldLineDs 管径
     * @param fieldLineMaterial 管材
     * @param workId 工作id
     * @param personnelId 采集人员id
     * @return FieldLineEntity
     */
    @Override
    public FieldLineEntity saveOneFieldLine(String fieldLineStartPointName,
            BigDecimal fieldLineStartDeep, String fieldLineEndPointName,
            BigDecimal fieldLineEndDeep, String fieldLineDs, String fieldLineMaterial, Long workId,
            Long personnelId) {
        FieldLineEntity lineEntity = new FieldLineEntity();

        lineEntity.setFieldLineStartPointName(fieldLineStartPointName);
        lineEntity.setFieldLineStartDeep(fieldLineStartDeep);
        lineEntity.setFieldLineEndPointName(fieldLineEndPointName);
        lineEntity.setFieldLineEndDeep(fieldLineEndDeep);
        lineEntity.setFieldLineDs(fieldLineDs);
        lineEntity.setFieldLineMaterial(fieldLineMaterial);
        // 关联关系绑定
        lineEntity.setPersonnelId(personnelId);
        lineEntity.setWorkId(workId);
        return lineRepository.save(lineEntity);
    }

    /**
     * 保存外业采集线段
     *
     * @param fieldLineEntityList 外业采集线段列表
     * @return 外业采集线段列表
     */
    @Override
    public List<FieldLineEntity> saveFieldLine(List<FieldLineEntity> fieldLineEntityList) {
        try {
            return lineRepository.saveAll(fieldLineEntityList);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 查询所有
     *
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @return 外业采集线段列表
     */
    @Override
    public Page<FieldLineEntity> findAll(Integer pageNum, Integer pageSize) {
        return getFLineEntitys(pageNum, pageSize, null);
    }

    /**
     * 根据工程id查询所有
     *
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @param workId 工程id
     * @return 外业采集线段列表
     */
    @Override
    public Page<FieldLineEntity> findByWorkId(Integer pageNum, Integer pageSize, Long workId) {

        Specification<FieldLineEntity> spec = (Specification<FieldLineEntity>) (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder
                .equal(root.get("workId"), workId);
        return getFLineEntitys(pageNum, pageSize, spec);
    }

    /**
     * 根据采集人id查询所有
     *
     * @param personnelId 采集人id
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @return 外业采集线段列表
     */
    @Override
    public Page<FieldLineEntity> findByPersonnelId(Long personnelId, Integer pageNum,
            Integer pageSize) {
        Specification<FieldLineEntity> spec = (Specification<FieldLineEntity>) (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder
                .equal(root.get("personnelId"), personnelId);
        return getFLineEntitys(pageNum, pageSize, spec);
    }

    /**
     * 查询具体的csv文件 构造 FieldLineEntity
     *
     * @param personnelId 上传id
     * @param workid 工程id
     * @param filename 文件名
     * @return FieldLineEntity
     */
    @Override
    public List<FieldLineEntity> createList(Long personnelId, Long workid, String filename) {
        try {
            FileEntity fileEntity = CommonSpec.fileSpec(fileRepository, personnelId, workid, filename);

        Specification<FieldPointEntity> r = getFieldPointEntitySpecification(personnelId, workid);
        List<FieldPointEntity> allPoint = pointRepository.findAll(r);

            Iterator<CsvFieldLine> fieldLineIterator = CsvUtil
                    .csvFieldLineRender(fileEntity.getcPath());

            List<FieldLineEntity> rs = new ArrayList<>();
            while (fieldLineIterator.hasNext()) {
                CsvFieldLine next = fieldLineIterator.next();
                FieldLineEntity entity = new FieldLineEntity();
                // 设置csv中属性
                entity.setFieldLineStartPointName(next.getStartName());
                entity.setFieldLineStartDeep(next.getStartDeep());
                entity.setFieldLineEndPointName(next.getEndName());
                entity.setFieldLineEndDeep(next.getEndDeep());
                entity.setFieldLineDs(next.getDs());
                entity.setFieldLineMaterial(next.getMaterial());
                // 设置表关联属性
                entity.setPersonnelId(personnelId);
                entity.setWorkId(workid);
                entity.setFileId(fileEntity.getFileId());
                // 设置起点终点关联ID
                setStartEndId(entity, allPoint);
                rs.add(entity);
            }
            return rs;
        } catch (Exception e) {
            throw new RuntimeException("csv 解析异常");
        }

    }

    private void setStartEndId(FieldLineEntity entity, List<FieldPointEntity> allPoint) {
        for (int i = 0; i < allPoint.size(); i++) {
            FieldPointEntity fieldPointEntity = allPoint.get(i);
            if (fieldPointEntity.getFieldPointName()
                    .equals(entity.getFieldLineStartPointName())) {
                entity.setFieldLineStartPointId(fieldPointEntity.getFieldPointId());
            } else if (fieldPointEntity.getFieldPointName()
                    .equals(entity.getFieldLineEndPointName())) {
                entity.setFieldLineEndPointId(fieldPointEntity.getFieldPointId());
            }
        }
    }

    /**
     * 外业采集点查询条件
     *
     * @param personnelId 采集人id
     * @param workid 工程id
     * @return 查询条件
     */
    private Specification<FieldPointEntity> getFieldPointEntitySpecification(Long personnelId,
            Long workid) {
        return (Specification<FieldPointEntity>) (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder
                .and(
                        criteriaBuilder.equal(root.get("workId"), workid),
                        criteriaBuilder.equal(root.get("personnelId"), personnelId)
                );
    }

    /**
     * 获取外业采集线段列表
     *
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @param specV 过滤条件
     * @return 外业采集线段列表
     */
    private Page<FieldLineEntity> getFLineEntitys(Integer pageNum, Integer pageSize,
            Specification<FieldLineEntity> specV) {
        Sort sort = new Sort(Direction.DESC, "fieldLineId");
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize, sort);
        return lineRepository.findAll(specV, pageable);
    }
}
